package org.shiro.util;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.Authenticator;
import org.apache.shiro.authc.LogoutAware;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.shiro.entity.User;

import java.util.Collection;
import java.util.Objects;

/**
 * @author 党怡承
 * @version 1.0
 * @date 2021-04-24 13:35
 */
public class ShiroUtils {
  private static RedisSessionDAO redisSessionDAO = SpringUtils.getBean(RedisSessionDAO.class);
  private static final String LOGIN_USER_IN_SESSION = "login_user";

  /**
   * 将用户信息存入session
   *
   * @param user
   */
  public static void setUserInSession(User user) {
    Session session = getSession();
    session.setAttribute(LOGIN_USER_IN_SESSION, user);
  }

  /**
   * 从session中获取用户信息
   *
   * @return
   */
  public static User getUser() {
    Session session = getSession();
    return (User) session.getAttribute(LOGIN_USER_IN_SESSION);
  }

  /**
   * 获取当前用户session
   *
   * @return
   */
  public static Session getSession() {
    return SecurityUtils.getSubject().getSession();
  }

  /**
   * 获取当前用户信息
   *
   * @return
   */
  public static User getUserInfo() {
    return (User) SecurityUtils.getSubject().getPrincipal();
  }
  /**
   * 删除用户缓存信息
   *
   * @param username 用户名称
   * @param isRemoveSession 是否删除session，删除则需重新登录
   */
  public static void deleteCache(String username, boolean isRemoveSession) {
    // 从缓存中获取session
    Session session = null;
    // 获取当前已登录的用户session列表
    Collection<Session> sessions = redisSessionDAO.getActiveSessions();
    User userEntity;
    Object object = null;
    // 遍历Session,找到该用户名称对应的Session
    for (Session sess : sessions) {
      object = sess.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
      if (object == null) {
        continue;
      }
      userEntity = (User) ((SimplePrincipalCollection) object).getPrimaryPrincipal();
      if (userEntity == null) {
        continue;
      }
      if (Objects.equals(userEntity.getUsername(), username)) {
        session = sess;
        // 清除该用户以前登录时保存的session，强制退出-> 单用户登录处理
        if (isRemoveSession) {
          redisSessionDAO.delete(session);
        }
      }
    }
    if (session == null || object == null) {
      return;
    }
    // 删除session
    if (isRemoveSession) {
      redisSessionDAO.delete(session);
    }
    // 删除Cache，再访问受限接口时会重新授权
    DefaultWebSecurityManager webSecurityManager =
        (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
    Authenticator auth = webSecurityManager.getAuthenticator();
    ((LogoutAware) auth).onLogout((SimplePrincipalCollection) object);
  }

  /**
   * 从缓存中获取指定用户名的Session
   *
   * @param username
   * @return
   */
  public static Session getSessionByUserName(String username) {
    // 获取当前已登录的用户session列表
    Collection<Session> sessions = redisSessionDAO.getActiveSessions();
    User user;
    Object object;
    // 遍历Session,找到该用户名称对应的Session
    for (Session session : sessions) {
      object = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
      if (object == null) {
        continue;
      }
      user = (User) ((SimplePrincipalCollection) object).getPrimaryPrincipal();
      if (user == null) {
        continue;
      }
      if (Objects.equals(user.getUsername(), username)) {
        return session;
      }
    }
    return null;
  }
}
